package com.bbzn.user.client.controller;

import com.bbzn.user.client.aspect.OperationAnnotation;
import com.bbzn.user.client.constant.CrudConstant;
import com.bbzn.user.client.constant.PermissionConstant;
import com.bbzn.user.client.constant.RoleConstant;
import com.bbzn.user.client.dataobject.Role;
import com.bbzn.user.client.dataobject.RolePermission;
import com.bbzn.user.client.dataobject.SystemParam;
import com.bbzn.user.client.dataobject.UserRole;
import com.bbzn.user.client.exception.DefinitException;
import com.bbzn.user.client.service.*;
import com.bbzn.user.client.utils.BaseApiService;
import com.bbzn.user.client.utils.BaseResponse;
import com.bbzn.user.client.utils.MayiktJwtUtils;
import com.bbzn.user.client.utils.OptionalBean;
import com.bbzn.user.client.vo.req.RolePermissionListVO;
import com.bbzn.user.client.vo.req.RoleVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author wulongbo
 * @Date 2021/11/4 18:38
 * @Version 1.0
 */

@RestController
@RequestMapping("/role")
@Slf4j
@Api(value = "role", tags = "角色管理器")
public class RoleController extends BaseApiService {

    @Autowired
    private CommonService commonService;

    @Autowired
    private SystemParamByCacheService systemParamByCacheService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private RolePermissionService rolePermissionService;

    @Autowired
    private UserRoleService userRoleService;


    @PostMapping("/getRole")
    @OperationAnnotation(content = "查询角色")
    public BaseResponse getRole(HttpServletRequest request) throws Exception {
        Long id = commonService.getUserId(request);
        Role query = new Role();
        query.setUserId(id);
        List<Role> roles = roleService.findByAll(query);
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        SystemParam systemParam = systemParamByCacheService.getValues(CrudConstant.CRUD_ENUM, CrudConstant.SELECT_SUCCESS_PREFIX + language);
        return setResultSuccess(systemParam.getMassage(), roles);
    }

    @PostMapping("/addRole")
    @OperationAnnotation(content = "添加角色")
    public BaseResponse addRole(HttpServletRequest request, @RequestBody RoleVO roleVO) throws Exception {
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        Long id = commonService.getUserId(request);
        if (CollectionUtils.isEmpty(roleVO.getPermIds())) {
            SystemParam systemParam = systemParamByCacheService.getValues(PermissionConstant.PER_ENUM, PermissionConstant.PER_NO_ID_PREFIX + language);
            throw new DefinitException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, systemParam.getMassage());
        }
        if (!OptionalBean.ofNullable(roleVO.getRoleName()).isPresent()) {
            SystemParam systemParam = systemParamByCacheService.getValues(RoleConstant.ROLE_ENUM, RoleConstant.ROLE_NO_NAME_PREFIX + language);
            throw new DefinitException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, systemParam.getMassage());
        }
        // 角色名称不能重复
        Role repeat = new Role();
        repeat.setUserId(id);
        repeat.setRoleName(roleVO.getRoleName());
        List<Role> repeats = roleService.findByAll(repeat);
        if (!CollectionUtils.isEmpty(repeats)) {
            SystemParam systemParam = systemParamByCacheService.getValues(RoleConstant.ROLE_ENUM, RoleConstant.ROLE_NAME_EXIST_PREFIX + language);
            throw new DefinitException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, systemParam.getMassage());
        }

        if (!OptionalBean.ofNullable(roleVO.getRoleDesc()).isPresent()) {
            SystemParam systemParam = systemParamByCacheService.getValues(RoleConstant.ROLE_ENUM, RoleConstant.ROLE_NO_ROLEDESC_PREFIX + language);
            throw new DefinitException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, systemParam.getMassage());
        }
        // 默认权限列表
        List<Long> defaultPermIds = rolePermissionService.findPermissionIdByRoleId(RoleConstant.ROLE_DEFAULT_ID);
        if (!roleVO.getPermIds().containsAll(defaultPermIds)) {
            SystemParam systemParam = systemParamByCacheService.getValues(PermissionConstant.PER_ENUM, PermissionConstant.PER_DEFAULT_PREFIX + language);
            throw new DefinitException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, systemParam.getMassage());
        }
        // 查询所有的资源id列表
        List<Long> allPermId = permissionService.getPermissions();
        if (!allPermId.containsAll(roleVO.getPermIds())) {
            SystemParam systemParam = systemParamByCacheService.getValues(PermissionConstant.PER_ENUM, PermissionConstant.PER_ID_ERROR_PREFIX + language);
            throw new DefinitException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, systemParam.getMassage());
        }

        // 新增角色
        int roleId = roleService.getMaxId() + 1;
        roleVO.setId(roleId);
        roleVO.setUserId(commonService.getUserId(request));
        roleVO.setCreateTime(new Date());
        roleVO.setCreatedBy(MayiktJwtUtils.getUsername(request, secretKey));
        roleService.insert(roleVO);

        // 新增角色资源
        List<RolePermission> param = roleVO.getPermIds().stream().map(
                permId -> {
                    return new RolePermission(roleId, permId);
                }
        ).collect(Collectors.toList());
        rolePermissionService.batchInsert(param);
        SystemParam systemParam = systemParamByCacheService.getValues(CrudConstant.CRUD_ENUM, CrudConstant.ADD_SUCCESS_PREFIX + language);
        return setResultSuccess(systemParam.getMassage());
    }

    @PostMapping("/updateRole")
    @OperationAnnotation(content = "修改角色")
    public BaseResponse updateRole(HttpServletRequest request, @RequestBody Role role) throws Exception {
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        if (!OptionalBean.ofNullable(role.getId()).isPresent()) {
            SystemParam systemParam = systemParamByCacheService.getValues(RoleConstant.ROLE_ENUM, RoleConstant.ROLE_NO_ID_PREFIX + language);
            throw new DefinitException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, systemParam.getMassage());
        }
        if ((!OptionalBean.ofNullable(role.getRoleName()).isPresent()) && (!OptionalBean.ofNullable(role.getRoleDesc()).isPresent())) {
            SystemParam systemParam = systemParamByCacheService.getValues(RoleConstant.ROLE_ENUM, RoleConstant.ROLE_NO_NAME_OR_DES_PREFIX + language);
            throw new DefinitException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, systemParam.getMassage());
        }
        role.setUpdateTime(new Date());
        role.setUpdatedBy(MayiktJwtUtils.getUsername(request, secretKey));
        roleService.updateByPrimaryKeySelective(role);
        SystemParam systemParam = systemParamByCacheService.getValues(CrudConstant.CRUD_ENUM, CrudConstant.MODIFY_SUCCESS_PREFIX + language);
        return setResultSuccess(systemParam.getMassage());
    }

    @PostMapping("/updateRolePermission")
    @OperationAnnotation(content = "修改角色对应的资源权限")
    public BaseResponse updateRolePermission(HttpServletRequest request, @RequestBody RolePermissionListVO list) throws Exception {
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        List<Long> permIds = list.getPermIds();
        Integer roleId = list.getRoleId();
        if (CollectionUtils.isEmpty(permIds)) {
            SystemParam systemParam = systemParamByCacheService.getValues(PermissionConstant.PER_ENUM, PermissionConstant.PER_NO_ID_PREFIX + language);
            throw new DefinitException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, systemParam.getMassage());
        }
        if (!OptionalBean.ofNullable(roleId).isPresent()) {
            SystemParam systemParam = systemParamByCacheService.getValues(RoleConstant.ROLE_ENUM, RoleConstant.ROLE_NO_ID_PREFIX + language);
            throw new DefinitException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, systemParam.getMassage());
        }
        if (roleId != RoleConstant.ROLE_DEFAULT_ID) {
            // 默认权限列表
            List<Long> defaultPermIds = rolePermissionService.findPermissionIdByRoleId(RoleConstant.ROLE_DEFAULT_ID);
            if (!permIds.containsAll(defaultPermIds)) {
                SystemParam systemParam = systemParamByCacheService.getValues(PermissionConstant.PER_ENUM, PermissionConstant.PER_DEFAULT_PREFIX + language);
                throw new DefinitException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, systemParam.getMassage());
            }
        }
        // 查询所有的资源id列表
        List<Long> allPermId = permissionService.getPermissions();
        if (!allPermId.containsAll(permIds)) {
            SystemParam systemParam = systemParamByCacheService.getValues(PermissionConstant.PER_ENUM, PermissionConstant.PER_ID_ERROR_PREFIX + language);
            throw new DefinitException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, systemParam.getMassage());
        }
        rolePermissionService.deleteByRoleId(roleId);

        // 新增角色资源
        List<RolePermission> param = permIds.stream().map(
                permId -> {
                    return new RolePermission(roleId, permId);
                }
        ).collect(Collectors.toList());
        rolePermissionService.batchInsert(param);
        SystemParam systemParam = systemParamByCacheService.getValues(CrudConstant.CRUD_ENUM, CrudConstant.MODIFY_SUCCESS_PREFIX + language);
        return setResultSuccess(systemParam.getMassage());
    }

    @PostMapping("/delRole")
    @OperationAnnotation(content = "删除角色")
    public BaseResponse delRole(HttpServletRequest request, @RequestBody Role role) throws Exception {
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        Integer roleId = role.getId();
        if (!OptionalBean.ofNullable(roleId).isPresent()) {
            SystemParam systemParam = systemParamByCacheService.getValues(RoleConstant.ROLE_ENUM, RoleConstant.ROLE_NO_ID_PREFIX + language);
            throw new DefinitException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, systemParam.getMassage());
        }
        // 查询该角色下是否存在用户绑定
        UserRole query = new UserRole();
        query.setRoleId(roleId);
        List<UserRole> userRoles = userRoleService.findByAll(query);
        if (!CollectionUtils.isEmpty(userRoles)) {
            SystemParam systemParam = systemParamByCacheService.getValues(RoleConstant.ROLE_ENUM, RoleConstant.ROLE_EXIST_USER_PREFIX + language);
            throw new DefinitException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, systemParam.getMassage());
        }
        rolePermissionService.deleteByRoleId(roleId);
        roleService.deleteByPrimaryKey(roleId);
        SystemParam systemParam = systemParamByCacheService.getValues(CrudConstant.CRUD_ENUM, CrudConstant.DELETE_SUCCESS_PREFIX + language);
        return setResultSuccess(systemParam.getMassage());
    }

}
